#include "ProjectionTransform.h"
#define _USE_MATH_DEFINES
#include "math.h"


ProjectionTransform::ProjectionTransform():
	m_FieldOfView(45), 
	m_NearClip(.1f),
	m_FarClip(1000.0f),
	m_AspectRatio(1.0f),
	m_LeftHanded(true)
{
}

ProjectionTransform::ProjectionTransform(bool leftHanded):
	m_FieldOfView(45), 
	m_NearClip(.1f),
	m_FarClip(1000.0f),
	m_AspectRatio(1.0f),
	m_LeftHanded(leftHanded)
{
}

ProjectionTransform::~ProjectionTransform(void)
{
}

void ProjectionTransform::SetProjectionParameters(float fieldOfView,float nearClip, float farClip,float aspectRatio)
{
	m_FieldOfView = (float)(fieldOfView*M_PI/180.0);
	m_NearClip = nearClip;
	m_FarClip = farClip;
	m_AspectRatio = aspectRatio;
	m_Changed = true;
}

void ProjectionTransform::ResetTransformParameters()
{
	m_FieldOfView=0;
	m_NearClip = 0;
	m_FarClip = 0;
	m_AspectRatio = 1;
	m_Changed = true;
}

void ProjectionTransform::RecalculateMatrix() const
{
	float angle = m_FieldOfView/2;
	float yScale = 1/tan(angle);
	float xScale = yScale / m_AspectRatio;
	// row 0
	m_CompiledMatrix.SetRow(0,xScale,0,0,0);
	// row 1
	m_CompiledMatrix.SetRow(1,0,yScale,0,0);
	// row 2
	float zScale = m_FarClip/(m_FarClip-m_NearClip);
	
	if (m_LeftHanded)
		m_CompiledMatrix.SetRow(2,0,0,zScale,1);
	else
		m_CompiledMatrix.SetRow(2,0,0,zScale,-1);
	// row 3 
	m_CompiledMatrix.SetRow(3,0,0, - m_NearClip * m_FarClip / (m_FarClip-m_NearClip),0);
	
}
